/*
 * Google map V3 API
 */
var INFINITY = window.INFINITY || {};
INFINITY.GMap = new Class({
    Implements: Options,
    options: {
        width: 700,
        height: 400,
        km: 100,
        center: {
            lat: -34.397,
            lng: 150.644
        },
        zoom: 8,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    },

    getMap: function(){
        return this.map;
    },
    
    initialize: function(element, options){
        this.element = element;
        this.setOptions(options);
        this.markers = [];
        
        with(this.element) {
            style.width = this.options.width + "px";
            style.height = this.options.height + "px";
        }
        
        var latlng = new google.maps.LatLng(this.options.center.lat, this.options.center.lng);
        var myOptions = {
            zoom: this.options.zoom,
            center: latlng,
            mapTypeId: this.options.mapTypeId
        };

        this.map = new google.maps.Map(this.element, myOptions);
    },
    
    fitCircle: function(latlng, km) {
        var circle = new google.maps.Circle({
            center: latlng,
            radius: 1000 * (km - 3),
            //fillOpacity: 0.0,
            //strokeOpacity: 0.0,
            map: this.map
        });
        var bounds = circle.getBounds();
        this.map.fitBounds(bounds);            
    },
    
    /*
    options: {lat:0, lng:0, title:"", info:"", icon:"xxx.png", shadow:"xxx.png"}
    options: {position:position, title:"", info:"", icon:"xxx.png", shadow:"xxx.png"}
    */
    addMarker: function(options) {
    	var position;
    	if(options.position != undefined) {
    		position = options.position;
    	} else {
    		position = new google.maps.LatLng(options.lat, options.lng);
    	}
    	var markerOptions = {
            position: position,
            title: options.title,
            map: this.map,
            animation: google.maps.Animation.DROP
       	};

        if(options.icon != undefined) {
            var pinShadow = new google.maps.MarkerImage(
                options.icon,
                null,
                null,
                new google.maps.Point(0, 32), 
                new google.maps.Size(32, 32)
            );
            markerOptions.icon = pinShadow;
        }

        if (options.shadow != undefined) {
            var pinShadow = new google.maps.MarkerImage(
                options.shadow,
                null,
                null,
                new google.maps.Point(0, 32),
                new google.maps.Size(59, 32)
            );
            markerOptions.shadow = pinShadow;
        }

        var marker = new google.maps.Marker(markerOptions);
  
  		if(options.info != undefined) {
	        var infowindow = new google.maps.InfoWindow({
	            content: "<div class=\"marker-title\">"+options.title+"</div>"+
                    "<div class=\"marker-info\">"+options.info+"</div>"
	        });
	  
	        google.maps.event.addListener(marker, 'click', function() {
	            infowindow.open(this.map, marker);
	        });
  		}
  		this.markers.push(marker);
  		
  		return marker;
    },
    
    deleteAllMarker: function(){
    	for(i in this.markers) {
    		this.markers[i].setMap(null);
    	}
    	this.markers.length = 0;
    },
    
    addEventListener: function(eventName, callback) {
		google.maps.event.addListener(this.map, eventName, callback);
    },
    
    toAddress: function(address, title, fn) {
    	var that = this;
    	this.geocode(address, function(latlng) {
    		that.map.setCenter(latlng);
    		that.addMarker({position:latlng, title:title, info:address});
			fn.apply(latlng);
    	});
    },
    
    geocode: function(address, callback) {
        var geocoder = new google.maps.Geocoder();
        geocoder.geocode( {'address': address}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                var location = results[0].geometry.location;
                var latlng = new google.maps.LatLng(location.lat(), location.lng());
                callback(latlng);
            } else {
              alert("Geocode was not successful for the following reason: " + status);
            }
        });
    },

    loadKml: function (url) {
        var Layer = new google.maps.KmlLayer(url, { suppressInfoWindows: false });
        Layer.setMap(this.map);
    },
    
    directions: function (latlngs) {
        if (latlngs.length < 2) return;
    	this.directionsService = this.directionsService != undefined ? this.directionsService : new google.maps.DirectionsService();
    	this.directionsDisplay = this.directionsDisplay != undefined ? this.directionsDisplay : new google.maps.DirectionsRenderer();
    	
    	this.directionsDisplay.setMap(this.map);
    	var that = this;
    	if (latlngs.length == 2) {
    	    var request = {
    	        origin: latlngs[0],
    	        destination: latlngs[1],
    	        travelMode: google.maps.TravelMode.DRIVING
    	    };
    	}
    	if (latlngs.length > 2) {
    	    var waypts = [];
    	    for (var i = 1; i < latlngs.length-1; i++) {
    	        waypts.push({
    	            location: latlngs[i],
    	            stopover: true
    	        });
    	    }
    	    var request = {
    	        origin: latlngs[0],
    	        destination: latlngs[latlngs.length-1],
    	        waypoints: waypts,
    	        optimizeWaypoints: true,
    	        travelMode: google.maps.TravelMode.DRIVING
    	    };
    	}

    	this.directionsService.route(request, function (response, status) {
    	    if (status == google.maps.DirectionsStatus.OK) {
    	        that.directionsDisplay.setDirections(response);
    	    }
    	});
    }
});